Skip to content

Conversation

@brant-livefront
Copy link
Contributor

📔 Objective

We recently got a few more specifics from the Datadog team on the existing pull-based integration. In order to support identical data being sent as part of our new push-based integration, we need a few more dynamic fields to enrich the data.

This PR adds these new dynamic fields.

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@brant-livefront brant-livefront requested a review from a team as a code owner October 31, 2025 19:16
@brant-livefront brant-livefront changed the title Add template properites for Datadog Add template properties for Datadog Oct 31, 2025
@claude
Copy link

claude bot commented Oct 31, 2025

Claude finished @brant-livefront's task —— View job


PR Review Complete

Summary of Changes

This PR adds three new template properties (UserType, ActingUserType, and the underlying User/ActingUser objects) to the Datadog integration template system. The implementation includes:

  • New properties in IntegrationTemplateContext for user type information
  • New repository method GetDetailsByOrganizationIdUserIdAsync in both Dapper and EF implementations
  • Optimized database queries using a dedicated stored procedure
  • Template processor methods to detect when user details are required
  • Comprehensive unit tests for all new functionality

Changes since last review: The latest commits refactored the implementation to use a dedicated stored procedure instead of inline queries, improving maintainability and performance.


Critical Issues

1. Missing Input Validation in Stored Procedure (Medium Priority)

Location: src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadByOrganizationIdUserId.sql:8-15

The stored procedure doesn't validate that the input GUIDs are not empty/default GUIDs. While SQL Server will handle this gracefully, it's a minor performance concern.

-- Consider adding validation
IF @OrganizationId = '00000000-0000-0000-0000-000000000000' OR @UserId = '00000000-0000-0000-0000-000000000000'
BEGIN
    RETURN
END

However, this is low priority since the application layer should handle this, and the query will simply return no results if invalid GUIDs are passed.


Suggested Improvements

1. Inconsistent Template Detection Logic

Location: src/Core/AdminConsole/Utilities/IntegrationTemplateProcessor.cs:33-75

The template detection methods all check for UserType but the Type property on events already exists. Consider if #Type# (event type) could be confused with #UserType# (organization user type). The current implementation correctly uses #UserType# and #ActingUserType#, but this could be documented.

Suggestion: Add XML comments to clarify the distinction:

/// <summary>
/// Checks if the template requires loading User details from the repository.
/// Detects tokens: #UserName#, #UserEmail#, #UserType# (OrganizationUserType, not EventType)
/// </summary>
public static bool TemplateRequiresUser(string template)

2. Potential N+1 Query Issue with Template Context Building

Location: src/Core/AdminConsole/Services/Implementations/EventIntegrations/EventIntegrationHandler.cs:104-118

When the same event contains both UserId and ActingUserId pointing to the same user, two separate database calls are made. For most use cases this is fine, but if the same user ID appears in both fields, a caching layer or check could avoid the duplicate query.

Example optimization (optional)
if (IntegrationTemplateProcessor.TemplateRequiresUser(template) && eventMessage.UserId.HasValue)
{
    context.User = await organizationUserRepository.GetDetailsByOrganizationIdUserIdAsync(
        organizationId: organizationId,
        userId: eventMessage.UserId.Value
    );
}

if (IntegrationTemplateProcessor.TemplateRequiresActingUser(template) && eventMessage.ActingUserId.HasValue)
{
    // Optimize if acting user is the same as user
    if (eventMessage.ActingUserId == eventMessage.UserId && context.User != null)
    {
        context.ActingUser = context.User;
    }
    else
    {
        context.ActingUser = await organizationUserRepository.GetDetailsByOrganizationIdUserIdAsync(
            organizationId: organizationId,
            userId: eventMessage.ActingUserId.Value
        );
    }
}

Priority: Low - This is a minor optimization that would only matter under high load, and the current implementation is clearer.

3. Missing Edge Case Test

Location: test/Core.Test/AdminConsole/Services/EventIntegrationHandlerTests.cs

There's no test for when a template references #UserType# but UserId is null. The current implementation handles this gracefully (won't fetch, property returns null), but an explicit test would document this behavior.

Suggested test:

[Theory, BitAutoData]
public async Task HandleEventAsync_UserTypeTemplateButNoUserId_DoesNotFetchUser(EventMessage eventMessage)
{
    var sutProvider = GetSutProvider(OneConfiguration("#UserType#"));
    eventMessage.OrganizationId = _organizationId;
    eventMessage.UserId = null; // Explicitly null
    
    await sutProvider.Sut.HandleEventAsync(eventMessage);
    
    await sutProvider.GetDependency<IOrganizationUserRepository>()
        .DidNotReceiveWithAnyArgs()
        .GetDetailsByOrganizationIdUserIdAsync(Arg.Any<Guid>(), Arg.Any<Guid>());
}

4. Migration Script Formatting Inconsistency

Location: util/Migrator/DbScripts/2025-11-05_00_OrganizationUserUserDetails_ReadByOrganizationIdUserId.sql:1

The migration script uses CREATE OR ALTER while the stored procedure definition uses CREATE. This is fine, but be consistent with project conventions. The migration approach is correct (idempotent), but verify this matches other migration scripts in the project.


Good Practices Observed

  • Comprehensive unit test coverage for all new functionality
  • Proper use of nullable reference types
  • Template detection optimization to avoid unnecessary DB calls
  • Consistent naming conventions across User and ActingUser properties
  • Use of stored procedures for database access (Dapper implementation)
  • Both Dapper and Entity Framework implementations provided
  • Proper use of StringComparison.Ordinal for performance

Action Items

  1. Optional: Add XML documentation comments to template detection methods to clarify #Type# vs #UserType# distinction
  2. Optional: Consider adding edge case test for null UserId with UserType template
  3. Verify: Ensure migration script format (CREATE OR ALTER) is consistent with project standards
  4. Consider: Document the performance characteristics of the new template properties in case high-volume integrations use them

Security & Performance Notes

Security: No sensitive data exposure concerns. User details are already organization-scoped through the repository query.

Performance: The implementation includes smart template detection to avoid unnecessary database calls. The new stored procedure is efficient (indexed lookup on OrganizationId + UserId).

Zero-Knowledge Compliance: No encryption-related changes; template system only exposes non-sensitive user metadata (name, email, type).


Overall, this is a well-implemented feature with good test coverage and proper architectural patterns. The suggested improvements are minor and optional.


@github-actions
Copy link
Contributor

github-actions bot commented Oct 31, 2025

Logo
Checkmarx One – Scan Summary & Details088ec0fd-72e2-44e0-a402-83c86039ecff

New Issues (1)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 72
detailsMethod at line 72 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from user. This pa...
ID: ZWiNUnwMpO2ystke8b8neSGcojU%3D
Attack Vector

@codecov
Copy link

codecov bot commented Oct 31, 2025

Codecov Report

❌ Patch coverage is 54.09836% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.23%. Comparing base (ef665ba) to head (7148d36).

Files with missing lines Patch % Lines
...Console/Repositories/OrganizationUserRepository.cs 0.00% 13 Missing ⚠️
...Console/Repositories/OrganizationUserRepository.cs 0.00% 8 Missing ⚠️
...SharedWeb/Utilities/ServiceCollectionExtensions.cs 0.00% 4 Missing ⚠️
...tions/EventIntegrations/EventIntegrationHandler.cs 84.21% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@                     Coverage Diff                      @@
##           brant/unit-test-coverage    #6528      +/-   ##
============================================================
+ Coverage                     52.35%   56.23%   +3.88%     
============================================================
  Files                          1909     1909              
  Lines                         84640    84689      +49     
  Branches                       7561     7567       +6     
============================================================
+ Hits                          44312    47628    +3316     
+ Misses                        38625    35285    -3340     
- Partials                       1703     1776      +73     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@eliykat eliykat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume my review is not required because this is merging into a feature branch (so codeowner requirements don't apply) and Architecture Team are handling this work. Please re-request my review if this is not the case.

@brant-livefront brant-livefront requested a review from a team as a code owner November 5, 2025 22:57
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 5, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants